/**
 * Model package.
 */
package fr.umlv.m2.ig.model;

import java.awt.Point;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * This class defines the builder for the class {@link Station}.
 * 
 * @author Gambouele Bertrand.
 * @author Viravout Alexandre.
 */
public class StationOrCurveBuilder {

	/**
	 * The name attribute for the station which will be created.
	 */
	private String name;
	
	/**
	 * The type attribute for the station which will be created.
	 */
	private StationType type;

	/**
	 * The {@link Station} instance which will be returned by this builder.
	 */
	private Station station;

	/**
	 * Map of station coordinates for each line.
	 */
	private final Map<String, Point> coordinates;

	/**
	 * Map containing, for each line, a map of (destination, next station)
	 * from this station.
	 */
	private final Map<String, Map<String, String>> edges;

	/**
	 * Creates a {@link StationOrCurveBuilder} object.
	 * 
	 * @param stationName the name of the station which will be created by this builder.
	 */
	public StationOrCurveBuilder(final String stationName, final StationType stationType) {
		this.name = stationName;
		this.type = stationType;
		this.coordinates = new HashMap<String, Point>();
		this.edges = new HashMap<String, Map<String, String>>();
	}

	/**
	 * Creates a {@link StationOrCurveBuilder} object with the specified
	 * {@link Station} object.
	 * 
	 * @param station the {@link Station} object from which the builder will create the new object.
	 */
	public StationOrCurveBuilder(final Station station) {
		this(station.getName(), station.getType());
		this.station = station;
	}

	/**
	 * Sets coordinates of the station for the specified line.
	 * 
	 * @param lineName the line name.
	 * @param x the x coordinate.
	 * @param y the y coordinate.
	 */
	public void setCoordinates(final String lineName, final int x, final int y) {
		this.coordinates.put(lineName, new Point(x, y));
	}

	/**
	 * Adds a new edge in the station for the specified line.
	 * 
	 * @param lineName the line name.
	 * @param destination the destination station name.
	 * @param nextStation the next station name.
	 */
	public void addEdge(final String lineName, final String destination, final String nextStation) {
		Map<String, String> e = this.edges.get(lineName);

		if (e == null) {
			e = new HashMap<String, String>();
			this.edges.put(lineName, e);
		}

		e.put(destination, nextStation);
	}

	/**
	 * Returns the {@link Station} object created by the builder.
	 * 
	 * @return the built {@link Station} object.
	 */
	public Station getStation() {
		if (this.station == null) {
			this.station = new Station(this.name, this.type);
		}

		for (Entry<String, Point> entry : this.coordinates.entrySet()) {
			this.station.setCoordinates(entry.getKey(), entry.getValue());
		}

		for (Entry<String, Map<String, String>> entry : edges.entrySet()) {
			for (Entry<String, String> edge : entry.getValue().entrySet()) {
				this.station.addEdge(entry.getKey(), edge.getKey(), edge.getValue());
				this.station.setBusy(entry.getKey(), edge.getKey(), false);
			}
		}

		return this.station;
	}

}
